package com.founder.devwork.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.founder.devwork.dto.res.AuthorInfoDTO;
import com.founder.devwork.dto.res.DepartmentTreeDTO;
import com.founder.devwork.dto.res.EngineerDTO;
import com.founder.devwork.dto.res.EngineerStatsDTO;
import com.founder.devwork.entity.Department;
import com.founder.devwork.entity.Engineer;
import com.founder.devwork.entity.EngineerEmail;
import com.founder.devwork.service.CommitLogService;
import com.founder.devwork.service.DepartmentService;
import com.founder.devwork.service.EngineerEmailService;
import com.founder.devwork.service.EngineerService;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * EngineerController 用于处理与工程师相关的请求。
 * 提供部门树形结构、工程师列表、工程师统计等功能。
 */
@RestController
@RequestMapping("/api/engineer")
public class EngineerController {

    /**
     * 部门服务。
     */
    @Autowired
    private DepartmentService departmentService;

    /**
     * 工程师服务。
     */
    @Autowired
    private EngineerService engineerService;

    /**
     * 工程师邮箱服务。
     */
    @Autowired
    private EngineerEmailService engineerEmailService;

    @Autowired
    private CommitLogService commitLogService;

    /**
     * 获取部门树形结构。
     * @return 部门树形结构
     */
    @GetMapping("/departments/tree")
    public List<DepartmentTreeDTO> getDepartmentTree() {
        // 获取所有部门
        List<Department> departments = departmentService.list();

        // 构建树形结构
        return buildDepartmentTree(departments);
    }

    /**
     * 构建部门树形结构
     * @param departments 部门列表
     * @return 部门树形结构
     */
    private List<DepartmentTreeDTO> buildDepartmentTree(List<Department> departments) {
        Map<String, DepartmentTreeDTO> departmentMap = new HashMap<>();
        List<DepartmentTreeDTO> rootDepartments = new ArrayList<>();

        // 转换为DTO并建立映射
        for (Department dept : departments) {
            DepartmentTreeDTO dto = new DepartmentTreeDTO(dept.getId(), dept.getName(), dept.getParentId());
            departmentMap.put(dept.getId(), dto);
        }

        // 构建树形关系
        for (DepartmentTreeDTO dto : departmentMap.values()) {
            if (dto.getParentId() == null || dto.getParentId().isEmpty()) {
                // 根节点
                rootDepartments.add(dto);
            } else {
                // 子节点
                DepartmentTreeDTO parent = departmentMap.get(dto.getParentId());
                if (parent != null) {
                    parent.getChildren().add(dto);
                }
            }
        }

        // 计算每个部门的工程师数量（仅本部门）
        Map<String, Long> deptEngineerCounts = engineerService
            .listMaps(new QueryWrapper<Engineer>().select("dept_id AS deptId", "COUNT(*) AS count").groupBy("dept_id"))
            .stream()
            .collect(Collectors.toMap(m -> (String) m.get("deptId"), m -> (Long) m.get("count")));

        // 递归计算总工程师数（包括子部门）
        rootDepartments.forEach(node -> calculateEngineerCount(node, deptEngineerCounts));

        return rootDepartments;
    }

    /**
     * 计算工程师数量。
     * @param node 部门节点
     * @param deptEngineerCounts 部门工程师数量
     * @return 工程师数量
     */
    private long calculateEngineerCount(DepartmentTreeDTO node, Map<String, Long> deptEngineerCounts) {
        long count = deptEngineerCounts.getOrDefault(node.getId(), 0L);
        for (DepartmentTreeDTO child : node.getChildren()) {
            count += calculateEngineerCount(child, deptEngineerCounts);
        }
        node.setEngineerCount(count);
        return count;
    }

    /**
     * 获取指定部门的工程师列表。
     * @param deptId 部门ID
     * @return 工程师列表
     */
    @GetMapping("/engineers")
    public List<EngineerDTO> getEngineersByDept(@RequestParam String deptId) {
        return new ArrayList<>(departmentService.getAllEngineersByDeptId(deptId));
    }

    /**
     * 获取指定部门的全部工程师。
     * @param deptId 部门ID
     * @return 工程师集合
     */
    @GetMapping("/engineers/all")
    public Set<EngineerDTO> getAllEngineersByDept(@RequestParam String deptId) {
        return departmentService.getAllEngineersByDeptId(deptId);
    }

    /**
     * 获取工程师统计信息。
     * @param page 页码
     * @param size 每页条数
     * @param department 部门
     * @param name 工程师姓名
     * @param sortBy 排序字段
     * @param sortDirection 排序方向
     * @return 工程师统计信息
     */
    @GetMapping("/stats")
    public IPage<EngineerStatsDTO> getEngineerStats(
        @RequestParam(defaultValue = "1") int page,
        @RequestParam(defaultValue = "10") int size,
        @RequestParam(required = false) String department,
        @RequestParam(required = false) String name,
        @RequestParam(defaultValue = "totalChanges") String sortBy,
        @RequestParam(defaultValue = "DESC") String sortDirection
    ) {
        return engineerService.getEngineerStats(page, size, department, name, sortBy, sortDirection);
    }

    /**
     * 搜索工程师。
     * @param name 工程师姓名
     * @param page 页码
     * @param size 每页条数
     * @return 工程师列表
     */
    @GetMapping("/search")
    public Page<Engineer> search(@RequestParam String name, @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "20") int size) {
        QueryWrapper<Engineer> wrapper = new QueryWrapper<>();
        wrapper.like("name", name);
        wrapper.orderByAsc("name");
        return engineerService.page(new Page<>(page, size), wrapper);
    }

    /**
     * 获取工程师邮箱列表。
     * @param engineerId 工程师ID
     * @return 邮箱列表
     */
    @GetMapping("/emails")
    public List<EngineerEmail> getEmailsByEngineerId(@RequestParam String engineerId) {
        return engineerEmailService.getEmailsByEngineerId(engineerId);
    }

    /**
     * 添加工程师邮箱。
     * @param params 请求参数，包括 authorFullname, authorEmail, engineerId
     * @return 添加成功的 EngineerEmail 对象
     */
    @PostMapping("/emails")
    public EngineerEmail addEmail(@RequestBody Map<String, String> params) {
        String authorFullname = params.get("authorFullname");
        String authorEmail = params.get("authorEmail");
        String engineerId = params.get("engineerId");

        Engineer engineer = engineerService.getById(engineerId);
        String engineerName = engineer != null ? engineer.getName() : "";

        EngineerEmail newEmail = new EngineerEmail();
        newEmail.setAuthorFullname(authorFullname);
        newEmail.setAuthorEmail(authorEmail);
        newEmail.setEngineerId(engineerId);
        newEmail.setEngineerName(engineerName);
        newEmail.setCreatedAt(LocalDateTime.now());
        newEmail.setUpdatedAt(LocalDateTime.now());

        engineerEmailService.save(newEmail);
        return newEmail;
    }

    /**
     * 删除指定 ID 的工程师邮箱。
     * @param id 邮箱 ID
     * @return 删除成功返回 true，否则返回 false
     */
    @DeleteMapping("/emails/{id}")
    public boolean deleteEmail(@PathVariable String id) {
        return engineerEmailService.removeById(id);
    }

    /**
     * 获取所有distinct作者信息
     * @return List of AuthorInfoDTO
     */
    @GetMapping("/distinct-authors")
    public List<AuthorInfoDTO> getDistinctAuthors() {
        return commitLogService.getDistinctAuthors();
    }
}
